﻿//-----------------------------------------------------------------------
// <copyright file="CustomerService.cs" company="deixei.com">
//     Copyright (c) deixei.com. All rights reserved.
// </copyright>
// <author>Marcio Parente</author>
//---------------------------------------------------------------------
namespace Deixei.Domain.Service
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Deixei;
    using Deixei.Domain.Repository;
    using Deixei.Infrastructure;
    using Microsoft.Practices.Unity;
    using Microsoft.Practices.Unity.InterceptionExtension;

    /// <summary>
    /// Customer Service. All Customer related services are performed in this class. This has all business logic for customers management
    /// </summary>
    public class CustomerService : ICustomerService
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="CustomerService" /> class.
        /// </summary>
        public CustomerService()
        {
            Initialize(null, null, null);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="CustomerService" /> class.
        /// </summary>
        /// <param name="custRepo">The cust repo.</param>
        /// <param name="orderRepo">The order repo.</param>
        /// <param name="unitOfWork">The unit of work.</param>
        public CustomerService(ICustomerRepository custRepo, IOrderRepository orderRepo, IUnitOfWork unitOfWork)
        {
            Initialize(custRepo, orderRepo, unitOfWork);
        }

        /// <summary>
        /// Gets or sets the customer repository.
        /// </summary>
        /// <value>
        /// The customer repository.
        /// </value>
        [Dependency]
        public ICustomerRepository CustomerRepository { get; set; }

        /// <summary>
        /// Gets or sets the order repository.
        /// </summary>
        /// <value>
        /// The order repository.
        /// </value>
        [Dependency]
        public IOrderRepository OrderRepository { get; set; }

        /// <summary>
        /// Gets or sets the unit of work.
        /// </summary>
        /// <value>
        /// The unit of work.
        /// </value>
        [Dependency]
        public IUnitOfWork UnitOfWork { get; set; }

        /// <summary>
        /// Gets all customers.
        /// </summary>
        /// <returns>Queryable Customer</returns>
        public IQueryable<Customer> GetAllCustomers()
        {
            return CustomerRepository.GetAll();
        }

        /// <summary>
        /// Gets the customer.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns>Customer class</returns>
        public Customer GetCustomer(int id)
        {
            return CustomerRepository.Single(m => m.Id == id);
        }

        /// <summary>
        /// Adds the customer.
        /// </summary>
        /// <param name="newCustomer">The new customer.</param>
        /// <returns>Customer class</returns>
        public Customer AddCustomer(Customer newCustomer)
        {
            CustomerRepository.Add(newCustomer);
            CustomerRepository.UnitOfWork.Save();
            return newCustomer;
        }

        /// <summary>
        /// Updates the customer.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <param name="customer">The customer.</param>
        /// <returns>Custome Class</returns>
        public Customer UpdateCustomer(int id, Customer customer) 
        {
            Customer c = GetCustomer(id);
            c.Name = customer.Name;
            c.Code = customer.Code;
            c.Description = customer.Description;
            CustomerRepository.Update(c);
            CustomerRepository.UnitOfWork.Save();
            return c;
        }

        /// <summary>
        /// Deletes the customer.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns>customer class</returns>
        public Customer DeleteCustomer(int id)
        {
            Customer c = GetCustomer(id);
            CustomerRepository.Delete(c);
            return c;
        }

        /// <summary>
        /// Initializes the specified cust repo.
        /// </summary>
        /// <param name="custRepo">The cust repo.</param>
        /// <param name="orderRepo">The order repo.</param>
        /// <param name="unitOfWork">The unit of work.</param>
        private void Initialize(ICustomerRepository custRepo, IOrderRepository orderRepo, IUnitOfWork unitOfWork)
        {
            UnitOfWork = ( unitOfWork ?? DeixeiContainer.Container.Resolve<UnitOfWork>() );
            CustomerRepository = ( custRepo ?? DeixeiContainer.Container.Resolve<CustomerRepository>() );
            OrderRepository = ( orderRepo ?? DeixeiContainer.Container.Resolve<OrderRepository>() );
        }
    }

    /// <summary>
    /// Customer Service Interface
    /// </summary>
    public interface ICustomerService
    {
        /// <summary>
        /// Gets all customers.
        /// </summary>
        /// <returns>Queryable Customer object</returns>
        IQueryable<Customer> GetAllCustomers();
        /// <summary>
        /// Gets the customer.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns>Customer object</returns>
        Customer GetCustomer(int id);

        /// <summary>
        /// Adds the customer.
        /// </summary>
        /// <param name="newCustomer">The new customer.</param>
        /// <returns>Customer object</returns>
        Customer AddCustomer(Customer newCustomer);
        /// <summary>
        /// Updates the customer.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <param name="customer">The customer.</param>
        /// <returns>Customer object</returns>
        Customer UpdateCustomer(int id, Customer customer);
        /// <summary>
        /// Deletes the customer.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns>Customer object</returns>
        Customer DeleteCustomer(int id);
    }
}
